package com.sffzh.util.format;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.Random;

import com.sffzh.constant.Time;


public class DateUtil {
	
	private SimpleDateFormat format;
	private Date date;
	private String dateStr;
	private boolean nullPresentAsNoChars;//为true时表示当date为null或发生其他转换错误时字符串返回“”而不是null
	
	public DateUtil(){
		format= new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:SS");
	}
	public DateUtil(String pattern){
		setFormatPattern(pattern);
	}
	public DateUtil(Time.Pattern pattern){
		setFormatPattern(pattern);
	}
	
	private DateUtil setFormatPattern(String pattern){
		if(pattern!=null)this.format.applyPattern(pattern);
		else{
			System.err.println("设置的时间格式为空，设置未生效！！");
		}
		return this;
	}
	private DateUtil setFormatPattern(Time.Pattern pattern){
		return setFormatPattern(Time.getPatternStr(pattern));
	}
	
	public DateUtil setDate(Date date){
		if(date!=null){
			this.date=date;
			this.dateStr=format.format(date);
		}else{
			this.dateStr=nullPresentAsNoChars?"":null;
		}
		return this;
	}
	
	public Date getDate(){
		return this.date;
	}
	
	public DateUtil setDateStr(String dateStr) throws ParseException{
		if(dateStr!=null){
			this.dateStr=dateStr;
			this.date=format.parse(dateStr);
		}
		return this;
	}
	
	public String getDateStr(){
		return this.dateStr;
	}
    
	/**
	 * 在已创建DateUtil对象后更新时间日期格式，DateUtil中的日期时间字符串dateStr会同步更新掉
	 * @param pattern
	 * @return
	 */
	public DateUtil changePattern(String pattern){
		setFormatPattern(pattern);
		if(date!=null){
			this.dateStr=format.format(date);
		}else{
			this.dateStr=nullPresentAsNoChars?"":null;
		}
		return this;
	}
	public DateUtil changePattern(Time.Pattern pattern){
		return changePattern(Time.getPatternStr(pattern));
	}
	
	
  	/**
  	 * 按yyyy-MM-dd HH:mm:SS格式返回当前时间
  	 * @return
  	 */
  	public static String getCurrentDateTime() {
  		java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:SS");
  		return dateFormat.format(new Date());
  	}

  	public static String getCurrentDate(Time.Pattern pattern){
  		return new SimpleDateFormat(Time.getPatternStr(pattern)).format(new Date());
  	}
  	
  	public static String getCurrentDate(){
  		return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
  	}
    
  	public static Date parse(String timeStr,String timePattern) throws ParseException{
		SimpleDateFormat dateFormat = new SimpleDateFormat(timePattern);
		return dateFormat.parse(timeStr);
  	}
  	
  	public static Date parse(String timeStr,Time.Pattern timePattern) throws ParseException{
		SimpleDateFormat dateFormat = new SimpleDateFormat(Time.getPatternStr(timePattern));
		return dateFormat.parse(timeStr);
  	}
  	
  	/**
  	 * ☆
  	 * 将日期字符串换成Date类型，日期字符串必须为以下格式："yyyy-MM-dd HH:mm:ss"
  	 * @param str 日期字符串必须为以下格式："yyyy-MM-dd HH:mm:ss"
  	 * @return
  	 * @throws ParseException 
  	 */
	public static  Date parseDateTime(String str) throws ParseException {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return dateFormat.parse(str);
	}
	
  	/**
  	 * ☆
  	 * 将日期字符串换成Date类型，日期字符串必须为以下格式："yyyy-MM-dd"或"yyyy-MM-dd HH:mm:ss"
  	 * 方法会根据字符串长度选择哪一种进行转换，若长度小于10（去两端空格）则转为日期不带时间
  	 * @param str 日期字符串必须为以下格式："yyyy-MM-dd"
  	 * @return
  	 */
	public static  Date parseDateString(String str) {
		if(str==null){return null;}
		str=str.trim();
		SimpleDateFormat dateFormat;
		if(str.length()<=11){
			dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		}else{
			dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		}
		try {
			return dateFormat.parse(str);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 快速格式转换：当日期为null时返回null.如果要进行细粒度定义，请使用New DateUtil(pattern).setNullPresentAsNoChars(true).setDate(date).getDateStr()
	 * @param date
	 * @param timepattern
	 * @return
	 */
	public static String format(Date date ,String timepattern){
		if(date==null)return null;
		if(timepattern==null)return format(date);
		return new SimpleDateFormat(timepattern).format(date);
	}

	public static String format(Date date ,Time.Pattern timepattern){
		if(date==null)return null;
		return new SimpleDateFormat(Time.getPatternStr(timepattern)).format(date);
	}

	public static String format(Date date){
		if(date==null)return null;
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date);
	}

	/**
     * ☆
     * 得到标准格式的时间字符串
     * ��2004-4-30 17:27:03
     */
    public static String formatDateTime(Date date) {
    	if(date == null) {
    		return null;
    	}
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }
    
    /**
     * ☆
     * 将日期转换为yyyy-MM-dd的格式
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
    	if(date == null) {
    		return null;
    	}
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }
    
    
    /**
     * 检查字符串是否符合给定的日期时间格式，如是则原样返回，否则返回null
     * @param date
     * @param partten 格式：如yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String checkDateTimeStr(String date,String partten){
    	try {
			SimpleDateFormat sdf = new SimpleDateFormat(partten);
			sdf.parse(date);
			return date;
		} catch (Exception e) {
			e.printStackTrace();
		}
    	return null;
    }
    
    /**
     * 检查字符串是否为标准的日期格式或日期时间格式，如是则原样返回，否则返回null,格式为单日期或包括日期时间都会默认正确
     * @param date
     *  格式：为yyyy-MM-dd或为yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String checkDateFitStr(String date){
    	return checkDateStr(date)==null?checkDateTimeStr(date):checkDateStr(date);
    }

    /**
     * 检查字符串是否为标准的日期格式，如是则原样返回，否则返回null
     * @param date
     * @param partten 格式：默认为yyyy-MM-dd
     * @return
     */
    public static String checkDateStr(String date){
    	return checkDateTimeStr(date,"yyyy-MM-dd");
    }

    /**
     * 检查字符串是否为标准的日期时间格式，如是则原样返回，否则返回null
     * @param date
     * @param partten 格式：默认为yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String checkDateTimeStr(String datetime){
    	return checkDateTimeStr(datetime,"yyyy-MM-dd HH:mm:ss");
    }

    
    
    public static String addMon(int mon){
    	String str = "";
    	Format f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    	Calendar thisDay = Calendar.getInstance();
    	thisDay.add(Calendar.DAY_OF_MONTH, mon * 30); 
    	str = f.format(thisDay.getTime());
    	return str;
    }
    
    
    /**
     * ������10λ�ַ�
     * @param digCount
     * @return
     */
	public static String getRandomNumber(int digCount)
	{
		Random rnd = new Random();
		StringBuilder sb = new StringBuilder(digCount);
		for (int i = 0; i < 10; i++)
			sb.append((char) ('0' + rnd.nextInt(10)));
		return sb.toString();
	}
	
	/**
	 * 获取当前日期的前一天
	 * @return
	 */
	public static String getYesterday()
	{
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, -1);    //得到前一天
		Date date = calendar.getTime();
		DateFormat df = new SimpleDateFormat("yyyyMMdd");
		//System.out.println(df.format(date));
		
		return df.format(date);
	}
	
	/**
	 * 获取当前日期的前一天
	 * @return
	 */
	public static String getYesterdayTwo()
	{
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, -1);    //得到前一天
		Date date = calendar.getTime();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		//System.out.println(df.format(date));
		
		return df.format(date);
	}
	

	
	public static void generateFile(String dateTime,String fileName)
	{
		 String[] arrs={
		            "zhangsan,23,FuJian",
		            "lisi,30,ShangHai",
		            "wangwu,43,BeiJing",
		            "laolin,21,ChongQing",
		            "ximenqing,67,GuiZhou"
		        };
		
		File file = new File(fileName);
		
		FileWriter fw  = null;
		
		try
		{
			fw = new FileWriter(file);
			
			//一行一行写入指定文件
		    BufferedWriter  bw=new BufferedWriter(fw);

		    for(String arr:arrs)
		    {
		            bw.write(arr+"\t\n");
		    }
		    bw.close();
		    fw.close();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}
	    
		
		
	}
	
	/**
	 * 针对有间隔符的日期/时间进行比较，看dateTime是否处于startTime和endTime之间
	 * 如果startTime为null则表示对起始时间无限制；如果endTime为Null则表示对结束时间无限制
	 * 
	 * 参与对比的时间字符串必须采用同一格式系统，或者间隔符位置相同。如2015-12-12 12：12：12和2012-09-23可以参与比较，但日期和时间不能相比。
	 * 2013-12-30 15:33:32.454和2013年2月20日 9时12分由于间隔符位置相同，也可以相比较。
	 * 
	 * @return -1表示dateTime在时间域之前，1表示在时间域之后,-2表示出现异常
	 */
	public static int checkBetween(String dateTime,String startTime,String endTime){
		String divit="[^0-9]+";
		String[] date=dateTime.split(divit);
		String[] start = null;
		String[] end=null;
		boolean beforeStart=startTime!=null,
				afterEnd=endTime!=null;
		if(beforeStart){
			start=startTime.split(divit);
		}
		if(afterEnd){
			end=endTime.split(divit);
		}
		for(int i=0;i<date.length;i++){
			if(beforeStart&&(i>start.length||"".equals(start[i]))){
				beforeStart=false;
			}
			if(beforeStart){
				if(Integer.parseInt(start[i])<Integer.parseInt(date[i])){
					beforeStart=false;
				}else if(Integer.parseInt(start[i])>Integer.parseInt(date[i])){
					return -1;
				}
			}
			if(afterEnd&&(i>end.length||"".equals(end[i]))){
				afterEnd=false;
			}
			if(afterEnd){
				if(Integer.parseInt(end[i])>Integer.parseInt(date[i])){
					afterEnd=false;
				}else if(Integer.parseInt(end[i])<Integer.parseInt(date[i])){
					return 1;
				}
			}
			if((!beforeStart&&!afterEnd)||i==date.length-1){
				return 0;
			}
		}
		return -2;
	}
	
	public static void main(String[] args) {//TODO 测试函数
		System.err.println( checkBetween("2014-56-98 12:45:90.0","","2016年1月"));
		for(String a:"2015年56月98日 12:45:90.0".split("[^0-9]+")){
			System.out.print(a+"_");
		}
	}

	
	public static Date addMinute(Date date, int minute) {
		Calendar cal=Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MINUTE, minute);
		return cal.getTime();
	}
	
	public static Date addTime(Date date,int timeType,int value){
		Calendar cal=Calendar.getInstance();
		cal.setTime(date);
		cal.add(timeType, value);
		return cal.getTime();
	}
	
	
	public SimpleDateFormat getFormat() {
		return format;
	}

	public void setFormat(SimpleDateFormat format) {
		this.format = format;
	}


	public boolean isNullPresentAsNoChars() {
		return nullPresentAsNoChars;
	}
	
	/**
	 * 当对 nullPresentAsNoChars 进行设置时，dateStr会即时更新
	 * @param nullPresentAsNoChars 为true时表示当date为null或发生其他转换错误时字符串返回“”而不是null
	 * @return
	 */
	public DateUtil setNullPresentAsNoChars(boolean nullPresentAsNoChars) {
		this.nullPresentAsNoChars = nullPresentAsNoChars;
		if(nullPresentAsNoChars){
			if(this.dateStr==null)this.dateStr="";
		}else{
			if("".equals(this.dateStr))this.dateStr=null;
		}
		return this;
	}


	/**
	 * 用于日期排序，将日期数组从小到大排序
	 * @author sffzh
	 *
	 */
	public static class DateSortComprator implements Comparator<Date>{
		private boolean reverse=false;//
		/**
		 * 参数reverse表示反序：reverse为true时，排序将为从大到小排
		 * @param reverse
		 */
		public DateSortComprator(boolean reverse) {//
			this.reverse=true;
		}
		/**
		 * 日期从小到大排序
		 */
		public DateSortComprator() {
		}

		@Override
		public int compare(Date o1, Date o2) {
			if(o1.equals(o2))return 0;
			else if(o1.before(o2))
				return reverse?1:-1;
			else return reverse?-1:1;
		}
	}
}
